﻿#region ... Copyright Notice ...
/*
   Copyright 2008 Tyler Jensen

	Author: Tyler Jensen    http://www.tsjensen.com/blog

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
 */
#endregion

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Atrax.Library;

namespace Atrax.Library.Seo
{
	public class ContentAnalysisProcessor : IQueryProcessor
	{
		Query query = null;
		List<string> urls = new List<string>();

		public void Initialize(Query query)
		{
			this.query = query;
		}

		public QueryValidationResult Validate()
		{
			QueryValidationResult result = new QueryValidationResult() { IsValid = false, ValidationReport = "<errors><error>unknown</error></errors>" };
			try
			{
				StringBuilder sb = new StringBuilder();

				XDocument doc = XDocument.Parse(this.query.Request);
                var items = from x in doc.Descendants()  //"contentanalysisquery"
                            where x.Name == "url"
                            select x.Value;
								//select new { url = x.Element("url").Value };

				foreach (var i in items)
				{
					Uri u = new Uri(i);
					if (!u.IsAbsoluteUri)
					{
                        sb.Append("<error><invaliduri>" + i.ToXmlString() + "</invaliduri></error>");
					}
					else
                        urls.Add(i);
				}
				string errors = sb.ToString();
				if (errors.Length > 0)
				{
					result.IsValid = false;
					result.ValidationReport = "<validationreport><result>failure</result><errors>" + errors + "</errors></validationreport>";
				}
				else
				{
					result.IsValid = true;
					result.ValidationReport = "<validationreport><result>success</result></validationreport>";
				}
			}
			catch (Exception e)
			{
				result.IsValid = false;
				result.ValidationReport = "<validationreport><result>failure</result><errors><error>" + e.Message.ToXmlString() + "</error></errors></validationreport>";
			}
			return result;
		}

		public double GetProcessingTimeEstimate(int availableIpAddressCount)
		{
			return ((urls.Count * 2.0) / availableIpAddressCount) + (urls.Count * 3.0);
		}

		public InternetRequest[] CreateRequests()
		{
			List<InternetRequest> list = new List<InternetRequest>();
			foreach (string u in urls)
			{
				InternetRequest r = new InternetRequest() { Method = "GET", Url = u };
				list.Add(r);
			}
			return list.ToArray();
		}

		public QueryResultFragment ProcessResponse(InternetResponse response)
		{
			string text = InternetResponseParser.ConvertBodyToString(response);
			QueryResultFragment frag = new QueryResultFragment()
			{
				ResultFragment = "<result url=\"" + response.Request.Url.ToXmlString() + "\">" + text.ToXmlString() + "</result>",
				StatusCode = "200",
				StatusDescription = "OK"
			};
			return frag;
		}

		public QueryResult CreateResult(QueryResultFragment[] fragments)
		{
			QueryResult result = new QueryResult() 
			{ 
				Query = this.query, 
				StatusCode = "200", 
				StatusDescription = "OK", 
				ResultSchema = "http://tsjensen.com/contentanalysisresult" 
			};
			StringBuilder sb = new StringBuilder();
			foreach (var frag in fragments)
			{
				sb.AppendLine(frag.ResultFragment);
			}
			result.Result = "<contentanalysisresult>" + sb.ToString() + "</contentanalysisresult>";
			return result;
		}

		public Query Query
		{
			get
			{
				return this.query;
			}
		}

		public string GetSampleQueryRequest()
		{
			StringBuilder sb = new StringBuilder();
			sb.AppendLine("<contentanalysisquery>");
			sb.AppendLine("  <url>http://www.cnn.com/</url>");
			sb.AppendLine("  <url>http://www.codinghorror.com/blog/</url>");
			sb.AppendLine("</contentanalysisquery>");
			return sb.ToString();
		}
	}
}
